home *** CD-ROM | disk | FTP | other *** search
- ---COND.DOC---
-
- Conditional Assembly
- ----------- --------
-
- This assembler has a conditional assembly feature, that allows you to specify
- that blocks of source code will or will not be assembled, according to the
- values of equated user symbols. The controlling symbols can be declared in
- the program (and can thus be the result of assembly-time expressions), or they
- can be declared in the assembler invocation.
-
- You should keep in mind the difference between conditional assembly, invoked
- by #IF, and the structured-programming feature, invoked by IF without the
- pound-sign. #IF tests a condition at assembly-time, and can cause code to
- not be assembled and thus not appear in the program. IF causes code to be
- assembled that tests a condition at run-time, possibly jumping over code.
- The skipped code will always appear in the program.
-
- All conditional assembly lines are identified by a pound-sign # as the first
- non-blank character of a line. The pound-sign is followed by one of the four
- keywords IF, ELSEIF, ELSE or ENDIF.
-
- #IF starts a conditional-assembly block. On the same line, following the #IF,
- you provide a name. If the name is undefined, or if it has been equated to
- zero, then the following lines of code are skipped, up to the next matching
- #ELSEIF, #ELSE, or #ENDIF. If the name is non-zero, then the following lines
- of code are assembled normally. If a subsequent matching #ELSEIF or #ELSE is
- encountered, then code is skipped up to the matching #ENDIF.
-
- #ELSEIF provides a multiple-choice facility for #IF-blocks. You can give any
- number of #ELSEIFs between an #IF and its matching #ENDIF. Each #ELSEIF has a
- name following it on the same line. If the name following the #IF has zero
- value, then the assembler looks for the first non-zero name following an
- #ELSEIF, and assembles that block of code. If there are no non-zero #ELSEIFs,
- then the #ELSE-block (if there is one) is assembled.
-
- It is legal to provide an undefined name after #IF or #ELSEIF. The name is
- interpreted as being false (zero), with no error.
-
- You may precede the name in an #IF or #ELSEIF line with an exclamation point
- "!", which acts as a NOT-operator: code will be skipped if the name is non-zero
- instead of zero.
-
- #ELSE marks the beginning of code to be assembled if all the previous blocks
- of an #IF have been skipped over. There is no operand after the #ELSE. There
- can be at most one #ELSE in an #IF-block, and it must appear after any #ELSEIFs.
-
- #ENDIF marks the end of an #IF-block. There is no operand after #ENDIF.
-
- It is legal to have nested #IF-blocks; that is, #IF-blocks that are contained
- within other #IF-blocks. #ELSEIF, #ELSE, and #ENDIF always refer to the
- innermost nested #IF-block.
-
- As an example of conditional assembly, suppose that you have a program that
- comes in three versions: one for Texas, one for Oklahoma, and one for the
- rest of the nation. The three programs differ in a limited number of places.
- Instead of keeping three different versions of the source code, you can keep
- one version, and use conditional assembly on the boolean varibales TEXAS and
- OKLAHOMA to control the assembler output. A sample block would be:
-
- #if TEXAS
- DB 0,1,2,3
- #elseif OKLAHOMA
- DB 4,5,6,7
- #else
- DB 8,9,10,11
- #endif
-
- If a block of code is to be assembled only if TEXAS is false, then you would
- use the exclamation-point operator:
-
- #if !TEXAS
- DB 0FF
- #endif
-
-
- Conditional Assembly and Macros
-
- You may have conditional-assembly blocks either in macro-definitions or
- in macro expansions. The only limitation is that if you have an #IF-block
- in a macro expansion, the entire block (i.e., the matching #ENDIF) must
- appear in the same macro expansion. You cannot, for example, define a
- macro that is a synonym for #IF.
-
- To have your conditional-assembly block apply to the macro defintion, you
- provide the block normally within the defintion. For example:
-
- X1 EQU 0
- BAZ MACRO
- #if X1
- DB 010
- #else
- DB 011
- #endif
- #EM
- BAZ
- X1 EQU 1
- BAZ
-
- In the above sequence of code, the conditional-assembly block is acted upon
- when the macro BAZ is defined. The macro therefore consists of the single
- line DB 011, with all the conditional-assembly lines removed from the
- definition. Thus, both expansions of BAZ produce the object-code byte of
- 011, even though the local label X1 has turned non-zero for the second
- invocation.
-
- To have your conditional-assembly block appear in the macro expansion, you
- must literalize the pound-sign on each conditional-assembly line by giving
- two pound-signs:
-
- X1 EQU 0
- BAZ MACRO
- ##if X1
- DB 010
- ##else
- DB 011
- ##endif
- #EM
- BAZ
- X1 EQU 1
- BAZ
-
- Now the entire conditional-assembly block is stored in the macro defintion, and
- acted upon each time the macro is expanded. Thus, the two invocations of BAZ
- will produce the different object bytes 011 and 010, since X1 has become
- non-zero for the second expansion.
-
- You will usually want your conditional-assembly blocks to be acted upon at
- macro-definition time, to save symbol-table space. You will thus use the first
- form, with the single pound-signs.
-
-
- Conditional Assembly and the XREF Program
-
- In most cases, the XREF program will recognize conditional-assembly blocks, and
- ignore skipped-code in its XREF compilation. The last macro example above,
- however, is an example in which XREF will not skip the same blocks that the
- assembler will; because it falls under the following
-
- WARNING: The XREF program will use the value of all symbols as it existed at
- the end of assembly. XREF does not parse statements that change the value of
- local variables! Thus, if you have conditional assembly based on a variable
- whose value changes during assembly, XREF will compile different source than
- the assembler assembled.
-
- The above warning does not apply to invocation-variables, described below. If
- you wish to change the value of a conditional-control variable during assembly,
- and if you wish XREF to give accurate results, you should change the variable
- between file-names in the invocation, as described below.
-
-
- Declaring Variables in the Assembler Invocation
-
- To facilitate the effective use of conditional assembly, this assembler allows
- you to declare boolean (true-false) symbols in the command-line that invokes
- the assembler. The declarations can appear anywhere in the list of source file
- names. They are distinguished from the file names by a leading equals-sign =.
- To declare a symbol TRUE (value = 1), give the name after the equals-sign. DO
- NOT put any spaces between the equals-sign and the name! To declare a symbol
- FALSE (value = 0), you can give an equals-sign, an exclamation-point, then the
- name. Again, DO NOT embed any blanks! Example: if your source files are
- src1.8, src2.8, and src3.8, then you can assemble with TEXAS true by invoking
- the assembler as follows:
-
- a86 =TEXAS src1.8 src2.8 src3.8
-
- You can assemble with TEXAS explicitly set to FALSE as follows:
-
- a86 =!TEXAS src1.8 src2.8 src3.8
-
- Note that if TEXAS is used only as a conditional-assembly control, then you
- do not need to include the =!TEXAS in the invocation, because an undefined
- TEXAS will automatically be interpreted as false.
-
-
- Null Invocation Variable Names
-
- The assembler will ignore an equals-sign by itself in the invocation line,
- without error. This allows you to generate assembler-invocation lines using
- parameters that could be either boolean-variable-names, or null strings. For
- example, in the previously-mentioned TEXAS-OKLAHOMA-nation example, the program
- could be invoked via a .BAT file called "AMAKE.BAT", coded as follows:
-
- A86 =%1 *.8
-
- You invoke the assembler by typing one of the following:
-
- amake texas
- amake oklahoma
- amake
-
- The third line will produce the assembler-invocation A86 = *.8; causing no
- invocation-variables to be declared. Thus both TEXAS and OKLAHOMA will be
- false, which is exactly what you want for the rest-of-the-nation version of
- the program.
-
-
- Changing Values of Invocation Variables
-
- The usual prohibition against changing the value of a symbol that is not a
- local-label does not apply to invocation-variables. For example, suppose you
- have a conditional-control variable DEBUG, which will generate diagnostic code
- for debugging when it is true. Suppose further that you have already debugged
- source files src1.8 and src3.8; but you are still working on src2.8. You may
- invoke the assembler as follows:
-
- a86 src1.8 =DEBUG src2.8 =!DEBUG src3.8
-
- The variable DEBUG will be TRUE only during assembly of src2.8, just as you
- want.
-